home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 3 / Cream of the Crop 3.iso / utility / btoa52.zip / REPAIR.C < prev   
C/C++ Source or Header  |  1994-04-08  |  9KB  |  339 lines

  1. /* repair.c */
  2.  
  3. /* Written by Stefan Parmark. */
  4.  
  5. #include <stdio.h>
  6. #ifdef AMIGA
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #endif AMIGA
  10.  
  11. #include "btoa.h"
  12.  
  13. /* File names. */
  14. BYTE *diagnosisname   = "btoa.dia";
  15. BYTE *repairname      = "btoa.rep";
  16. BYTE *repairedname    = "btoa.rdy";
  17.  
  18. /* File headers. */
  19. BYTE *diagnosisheader = "xdiagnosis\n";
  20. BYTE *repairheader    = "xrepair\n";
  21.  
  22.  
  23. /* Produce diagnosis file from diagnoses records created by atob(). */
  24. /* It contains the lines immediately before and after the error     */
  25. /* sequence.                                                        */
  26. void producediagnosis(diagnosislist, infile)
  27. register struct Diagnosis *diagnosislist;
  28. register FILE *infile;
  29. {
  30.   register FILE *diagnosisfile;
  31.   LONG startpos, endpos;
  32.   register LONG currentpos;
  33.   extern BYTE *diagnosisname, *diagnosisheader, buffer[BUFSIZE];
  34.  
  35.   currentpos = ftell(infile);
  36.  
  37.   if ((diagnosisfile = fopen_write(diagnosisname)) != NULL)
  38.   {
  39.     fprintf(stderr, "btoa: Diagnosis output to '%s'.\n", diagnosisname);
  40.  
  41.     fputs(diagnosisheader, diagnosisfile);
  42.     do
  43.     {
  44.       /* Extract startpos & endpos from diagnosislist. */
  45.       outdiagnosislist(diagnosislist, &startpos, &endpos);
  46.  
  47.       if (startpos != -1)
  48.       {
  49.         /* Print line before error. */
  50.         fseek(infile, startpos, 0);
  51.         fgets(buffer, BUFSIZE, infile);
  52.         fputs(buffer, diagnosisfile);
  53.  
  54.         /* Print line after error. */
  55.         fseek(infile, endpos, 0);
  56.         fgets(buffer, BUFSIZE, infile);
  57.         fputs(buffer, diagnosisfile);
  58.       }
  59.     }
  60.     while (startpos != -1);
  61.     fputs(diagnosisheader, diagnosisfile);
  62.  
  63.     fclose(diagnosisfile);
  64.   }
  65.  
  66.   /* Move file pointer to where it was when we entered. */
  67.   fseek(infile, currentpos, 0);
  68. }
  69.  
  70.  
  71. /* Insert two file positions into diagnosislist. */
  72. void intodiagnosislist(diagnosislist, startpos, endpos)
  73. register struct Diagnosis *diagnosislist;
  74. register LONG startpos, endpos;
  75. {
  76.   register struct Diagnosis *diagnosisitem, *lastitem;
  77.  
  78.   diagnosisitem = (struct Diagnosis *)malloc(sizeof(struct Diagnosis));
  79.   diagnosisitem->startpos = startpos;
  80.   diagnosisitem->endpos = endpos;
  81.   diagnosisitem->next = NULL;
  82.  
  83.   if ((lastitem = diagnosislist->last) == NULL)  /* List is empty */
  84.     diagnosislist->next = diagnosislist->last = diagnosisitem;
  85.   else
  86.   {
  87.     if (lastitem->endpos >= startpos)
  88.     {
  89.       lastitem->endpos = endpos;
  90.       free((BYTE *) diagnosisitem);
  91.     }
  92.     else
  93.     {
  94.       lastitem->next = diagnosisitem;
  95.       diagnosislist->last = diagnosisitem;
  96.     }
  97.   }
  98. }
  99.  
  100.  
  101. /* Extract two file positions from diagnosislist. */
  102. void outdiagnosislist(diagnosislist, startpos, endpos)
  103. register struct Diagnosis *diagnosislist;
  104. LONG *startpos, *endpos;
  105. {
  106.   register struct Diagnosis *diagnosisitem;
  107.  
  108.   if ((diagnosisitem = diagnosislist->next) == NULL)  /* List is empty */
  109.     *startpos = *endpos = -1;
  110.   else
  111.   {
  112.     *startpos = diagnosisitem->startpos;
  113.     *endpos = diagnosisitem->endpos;
  114.  
  115.     diagnosislist->next = diagnosisitem->next;
  116.     free((BYTE *)diagnosisitem);
  117.     if (diagnosislist->next == NULL)
  118.       diagnosislist->last = NULL;
  119.   }
  120. }
  121.  
  122.  
  123. /* Copy infile to outfile until searchstring is found. If outfile */
  124. /* is NULL nothing will be written.                               */
  125. BYTE copyfile(infile, outfile, searchstring)
  126. register FILE *infile, *outfile;
  127. register BYTE *searchstring;
  128. {
  129.   register BYTE stop, error;
  130.   static BYTE copybuffer[BUFSIZE];
  131.  
  132.   stop = error = FALSE;
  133.   while (!(stop || error))
  134.     if (readbuffer(copybuffer, "archive", infile))
  135.       error = TRUE;
  136.     else
  137.     {
  138.       if (outfile != NULL)
  139.         fputs(copybuffer, outfile);
  140.       if (strcmp(copybuffer, searchstring) == 0)
  141.         stop = TRUE;
  142.     }
  143.  
  144.   return(error);
  145. }
  146.  
  147.  
  148. /* Read a line from infile into buffer. Returns TRUE if */
  149. /* end-of-file has been reached.                        */
  150. BYTE readbuffer(buffer, errormsg, infile)
  151. register BYTE *buffer, *errormsg;
  152. register FILE *infile;
  153. {
  154.   register BYTE error;
  155.  
  156.   error = FALSE;
  157.   if (fgets(buffer, BUFSIZE, infile) == NULL)
  158.   {
  159.     fprintf(stderr, "btoa: Unexpected end of %s file.\n", errormsg);
  160.     error = TRUE;
  161.   }
  162.  
  163.   return(error);
  164. }
  165.  
  166.  
  167. FILE *fopen_read(filename)
  168. register BYTE *filename;
  169. {
  170.   register FILE *infile;
  171.  
  172.   if ((infile = fopen(filename, "r")) == NULL)
  173.     fprintf(stderr, "btoa: Can't open '%s' for input.\n", filename);
  174.  
  175.   return(infile);
  176. }
  177.  
  178.  
  179. FILE *fopen_write(filename)
  180. register BYTE *filename;
  181. {
  182.   register FILE *outfile;
  183.  
  184.   if ((outfile = fopen(filename, "w")) == NULL)
  185.     fprintf(stderr, "btoa: Can't open '%s' for output.\n", filename);
  186.  
  187.   return(outfile);
  188. }
  189.  
  190.  
  191. /* Extract lines from original archive to fix the damaged one. */
  192. BYTE producerepair(infile)
  193. register FILE *infile;
  194. {
  195.   register FILE *repairfile, *diagnosisfile;
  196.   register BYTE error, stop;
  197.   static BYTE *errormsg = "diagnosis";
  198.   extern BYTE *diagnosisname, *diagnosisheader, *repairname, *repairheader,
  199.               buffer[BUFSIZE];
  200.  
  201.   error = FALSE;
  202.   diagnosisfile = repairfile = NULL;
  203.  
  204.   fprintf(stderr, "btoa: Repair output to '%s'.\n", repairname);
  205.   if ((diagnosisfile = fopen_read(diagnosisname)) == NULL)
  206.     error = TRUE;
  207.   else if ((repairfile = fopen_write(repairname)) == NULL)
  208.   {
  209.     fclose(diagnosisfile);
  210.     diagnosisfile = NULL;
  211.     error = TRUE;
  212.   }
  213.   else
  214.   {
  215.     /* Read until header is found. This makes it possible to   */
  216.     /* have junk before the header, such as an article header. */
  217.     do
  218.     {
  219.       if (readbuffer(buffer, errormsg, diagnosisfile))
  220.         error = TRUE;
  221.     }
  222.     while (!error && strcmp(buffer, diagnosisheader) != 0);
  223.     fputs(repairheader, repairfile);
  224.   }
  225.  
  226.   stop = FALSE;
  227.   while (!(error || stop))
  228.   {
  229.     /* Loop until header is found again. */
  230.  
  231.     if (readbuffer(buffer, errormsg, diagnosisfile))
  232.       error = TRUE;
  233.     else if (strcmp(buffer, diagnosisheader) == 0)
  234.       stop = TRUE;
  235.     else
  236.     {
  237.       /* Read until line before error is found. */
  238.       error = copyfile(infile, NULL, buffer);
  239.       if (!error)
  240.       {
  241.         /* Print line before error. */
  242.         fputs(buffer, repairfile);
  243.  
  244.         if (readbuffer(buffer, errormsg, diagnosisfile))
  245.           error = TRUE;
  246.         else
  247.         {
  248.           /* Print line after error */
  249.           fputs(buffer, repairfile);
  250.           /* Copy infile to repairfile until line after error */
  251.           error = copyfile(infile, repairfile, buffer);
  252.         }
  253.       }
  254.     }
  255.   }
  256.  
  257.   if (!error)
  258.     fputs(repairheader, repairfile);
  259.  
  260.   if (repairfile != NULL)
  261.     fclose(repairfile);
  262.   if (diagnosisfile != NULL)
  263.     fclose(diagnosisfile);
  264.  
  265.   return(error);
  266. }
  267.  
  268.  
  269. /* Repair damaged archive from repair file. */
  270. BYTE performrepair(infile)
  271. register FILE *infile;
  272. {
  273.   register FILE *repairfile, *outfile;
  274.   register BYTE error, stop;
  275.   static BYTE *errormsg = "repair";
  276.   extern BYTE *repairname, *repairedname, *repairheader, buffer[BUFSIZE];
  277.  
  278.   error = FALSE;
  279.   repairfile = outfile = NULL;
  280.  
  281.   if ((repairfile = fopen_read(repairname)) == NULL)
  282.     error = TRUE;
  283.   else if ((outfile = fopen_write(repairedname)) == NULL)
  284.   {
  285.     fclose(repairfile);
  286.     repairfile = NULL;
  287.     error = TRUE;
  288.   }
  289.   else
  290.   {
  291.     fprintf(stderr, "btoa: Repaired archive written to '%s'.\n", repairedname);
  292.  
  293.     /* Read until header is found. */
  294.     do
  295.     {
  296.       if (readbuffer(buffer, errormsg, repairfile))
  297.         error = TRUE;
  298.     }
  299.     while (!error && strcmp(buffer, repairheader) != 0);
  300.   }
  301.  
  302.   stop = FALSE;
  303.   while (!(error || stop))
  304.   {
  305.     /* Loop until header is found. */
  306.  
  307.     if (readbuffer(buffer, errormsg, repairfile))
  308.       error = TRUE;
  309.     else if (strcmp(buffer, repairheader) == 0)
  310.       stop = TRUE;
  311.     else
  312.     {
  313.       /* Read and write until line before error. */
  314.       error = copyfile(infile, outfile, buffer);
  315.       if (!error)
  316.         if (readbuffer(buffer, errormsg, repairfile))
  317.           error = TRUE;
  318.         else
  319.         {
  320.           /* Read and write until line after error. */
  321.           error = copyfile(repairfile, outfile, buffer);
  322.           /* Skip until line after error */
  323.           copyfile(infile, NULL, buffer);
  324.         }
  325.     }
  326.   }
  327.  
  328.   if (!error)  /* Write rest of archive. */
  329.     while (fgets(buffer, BUFSIZE, infile) != NULL)
  330.       fputs(buffer, outfile);
  331.  
  332.   if (outfile != NULL)
  333.     fclose(outfile);
  334.   if (repairfile != NULL)
  335.     fclose(repairfile);
  336.  
  337.   return(error);
  338. }
  339.